package com.iup.tp.twitup.ihm;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

/**
 * Objet graphique permettant d'afficher une image dans un panel.
 * 
 * @author S.Lucas
 */
public class Image extends JPanel
{

  /**
   * serialVersionUID.
   */
  private static final long serialVersionUID = -7931142078099462537L;

  /**
   * Fichier image original.
   */
  protected File mFile;

  /**
   * Image bufferisée.
   */
  protected BufferedImage mImage;

  /**
   * Constructeur.
   * 
   * @param file
   *          , Fichier image original.
   * @param imageWidth
   *          , Largeur voulue de l'image.
   * @param imageHeight
   *          , Hauteur voulue de l'image.
   */
  public Image(File file, int imageWidth, int imageHeight)
  {
    this.mFile = file;

    try
    {
      this.load(imageWidth, imageHeight);
    }
    catch (Throwable t)
    {
      mImage = new BufferedImage(imageWidth, imageHeight, 1);
      System.err.println("Erreur lors du chargement du fichier image.");
      t.printStackTrace();
    }
  }

  /**
   * Chargement du fichier image (avec resize éventuel).
   * 
   * @param imageWidth
   *          , Largeur voulue de l'image.
   * @param imageHeight
   *          , Hauteur voulue de l'image.
   */
  protected void load(int imageWidth, int imageHeight)
  {
    try
    {
      mImage = ImageIO.read(mFile);

      // Resize de l'image
      if (mImage.getWidth() != imageWidth || mImage.getHeight() != imageHeight)
      {
        mImage = this.resizeImage(mImage, imageWidth, imageHeight);
      }

      this.setSize(new Dimension(mImage.getWidth(), mImage.getHeight()));
      this.setPreferredSize(new Dimension(mImage.getWidth(), mImage.getHeight()));
    }
    catch (IOException e)
    {
      System.err.println("Erreur lors de resize de l'image.");
      e.printStackTrace();
    }
  }

  /**
   * {@inheritDoc} <br>
   * Dessin du panel pour afficher l'image à la bonne taille.
   */
  @Override
  protected void paintComponent(Graphics g)
  {
    super.paintComponent(g);

    g.drawImage(mImage, 0, 0, mImage.getWidth(), mImage.getHeight(), null);
  }

  /**
   * Resize de l'image (prise en compte de la taile la plus petite)
   * 
   * @param original
   *          , Image bufferisée originale.
   * @param imageWidth
   *          , Largeur voule du l'image.
   * @param imageHeight
   *          , Hauteur voulue de l'image.
   * @return la nouvelle image à la taille demandée.
   */
  public BufferedImage resizeImage(BufferedImage original, int imageWidth, int imageHeight)
  {
    // Calcul des facteurs de resize
    double widthFactor = (double) imageWidth / original.getWidth();
    double heightFactor = (double) imageHeight / original.getHeight();

    double factor = Math.min(widthFactor, heightFactor);
    int newWidth = (int) (factor * original.getWidth());
    int newHeight = (int) (factor * original.getHeight());

    BufferedImage newImage = new BufferedImage(newWidth, newHeight, original.getType());

    Graphics2D g = newImage.createGraphics();

    g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g.drawImage(original, 0, 0, newWidth, newHeight, null);
    g.dispose();

    return newImage;
  }
}
